import Axios from "axios";
import type {
  AxiosRequestConfig,
  AxiosInstance,
  AxiosResponse,
  AxiosError,
} from "axios";
import { defaultConfig } from "./type";
import router from "../router";

class AxiosHttp {
  private instance: AxiosInstance;

  public constructor(config: AxiosRequestConfig) {
    this.instance = Axios.create(config);
    this.interceptors();
    this.responseInterceptors();
  }

  public get<T = any>(url: string, config?: AxiosRequestConfig): Promise<T> {
    return this.request<T>({ ...config, method: "GET", url });
  }

  public post<T = any>(
    url: string,
    data?: any,
    config?: AxiosRequestConfig,
  ): Promise<T> {
    return this.request<T>({ ...config, method: "POST", url, data });
  }

  public put<T = any>(
    url: string,
    data?: any,
    config?: AxiosRequestConfig,
  ): Promise<T> {
    return this.request<T>({ ...config, method: "PUT", url, data });
  }

  public delete<T = any>(url: string, config?: AxiosRequestConfig): Promise<T> {
    return this.request<T>({ ...config, method: "DELETE", url });
  }

  private interceptors() {
    this.instance.interceptors.request.use(
      (config) => {
        return config;
      },
      (error) => {
        return Promise.reject(error);
      },
    );
  }

  private responseInterceptors() {
    this.instance.interceptors.response.use(
      (response: AxiosResponse) => {
        // 如果返回401，跳转到登录界面
        if (response.data.code === 401) {
          router.push({ name: "Login" });
        }
        return response;
      },
      (error: AxiosError) => {
        return Promise.reject(error);
      },
    );
  }

  private request<T = any>(config: AxiosRequestConfig): Promise<T> {
    return new Promise<T>((resolve, reject) => {
      this.instance
        .request(config)
        .then((res: AxiosResponse<T>) => resolve(res.data))
        .catch((error: AxiosError) => {
          reject(error);
        });
    });
  }
}

const axiosHttp = new AxiosHttp(defaultConfig);

export default axiosHttp;
